class IUP_DETACH_BOX
-- Creates a detachable void container.
--
-- Dragging and dropping this element, it creates a new dialog composed by 
-- its child or elements arranged in it (for example, a child like IUP_VBOX or 
-- IUP_HBOX). During the drag, the ESC key can be pressed to cancel the action.
	
inherit
	IUP_CONTAINER
		redefine
			execute_detached,
			execute_restored
		end
	IUP_WIDGET_EXPAND
	IUP_WIDGET_WID
	IUP_WIDGET_FONT
	IUP_WIDGET_SIZE
	IUP_WIDGET_RASTERSIZE
	IUP_WIDGET_USERSIZE
	IUP_WIDGET_CLIENTSIZE
	IUP_WIDGET_CLIENTOFFSET
	IUP_WIDGET_POSITION
	IUP_WIDGET_MAXMIN_SIZE
	IUP_WIDGET_CHILD
	IUP_WIDGET_NAME
	IUP_WIDGET_CUSTOM_ATTRIBUTES

create {ANY}
	detach_box_empty,
	detach_box

feature {ANY}

	detach_box_empty
	   -- Create an empty detach box.
		local
			p, a_detach_box: POINTER
		do
			a_detach_box := int_detach_box (p)
			set_widget(a_detach_box)
		end
	
	detach_box (child: IUP_WIDGET)
	   -- Create a new detach box containing the widget.
		local
         a_detach_box: POINTER
		do
			a_detach_box := int_detach_box (child.widget)
			set_widget(a_detach_box)
		end

	-- Attributes
	set_bar_size (size: INTEGER)
		-- (non inheritable): controls the size of the bar handler. To 
		-- completely hide the bar set BARSIZE to 0. Default: 10.
		require
			size >= 0
		do
			iup_open.set_attribute(Current, "BARSIZE", size.out)
		end

	get_bar_size: INTEGER
		-- Return the size of the bar.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "BARSIZE")
			Result := str.to_integer
		end

	set_rgb_color (red, green, blue: INTEGER)
		-- Changes the color of the bar grip affordance. The value should be 
		-- given in "R G B" color style. Default: "160 160 160". When SHOWGRIP = 
		-- NO, this attribute sets the background color of the bar handler.
		do
			iup_open.set_attribute(Current, "COLOR", rgb_to_string(red, green, blue))
		end

	get_rgb_color: TUPLE[INTEGER, INTEGER, INTEGER]
		-- Return the RGB values of the bar color.
		do
			Result := iup_open.get_rgb(Current, "COLOR")
		end

	set_vertical_orientation
		-- (creation only): Sets a vertical orientation of the bar handler. The 
		-- direction of the resize is perpendicular to the orientation.
		-- This is the default value.
		do
			iup_open.set_attribute(Current, "ORIENTATION", "VERTICAL")
		end

	set_horizontal_orientation
		-- (creation only): Sets an horizontal orientation of the bar handler. 
		-- The direction of the resize is perpendicular to the orientation. 
		do
			iup_open.set_attribute(Current, "ORIENTATION", "HORIZONTAL")
		end

	is_vertical: BOOLEAN
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "ORIENTATION")

			if str.is_equal("VERTICAL") then
				Result := True
			else
				Result := False
			end
		end

	get_old_parent_widget: IUP_WIDGET
		-- (read only): returns the previous parent of the detached element. 
		-- Only valid after the element was detached.
		do
			Result := iup_open.get_attribute_widget(Current, "OLDPARENT_HANDLE")
		end

	get_old_brother_widget: IUP_WIDGET
		-- (read only): returns the previous reference child of the detached 
		-- element. Only valid after the element was detached. See iup_reparent 
		-- for a reference child definition.
		do
			Result := iup_open.get_attribute_widget(Current, "OLDBROTHER_HANDLE")
		end

	detach_widget
		-- (write-only): detach the box by creating a new dialog and placing the 
		-- detachbox as the child of the new dialog. The DETACHED callback is 
		-- called, use it to configure the new dialog. The handler is hidden, the 
		-- USERSIZE of the detachbox is set to the CURRENTSIZE of the child, and 
		-- the PARENTDIALOG of the new dialog is set to old dialog. To re-parent 
		-- the child we need to map the dialog before doing it, so to force a 
		-- dialog resize its size is reset before its is shown, to control the 
		-- dialog size use the child size. The new dialog is show at the current 
		-- cursor position, and the USERSIZE of the detachbox is reset. 
		do
			iup_open.set_attribute_null(Current, "DETACH")
		end

	restore_widget (name: STRING)
		-- (write-only): restore the box to its previous place (parent and 
		-- brother) and destroys the new dialog. Value can be the 
		-- string "NULL" or can be the name of a new parent when the control will 
		-- be appended. Use set_widget_name to associate an IUP_WIDGET to a 
		-- name. The handler is shown (if restored to inside a IUP_ZBOX, the 
		-- application must update the IUP_ZBOX child visibility manually).
		do
			if name.is_equal("NULL") then
				iup_open.set_attribute_null(Current, "RESTORE")
			else
				iup_open.set_attribute(Current, "RESTORE", name)
			end
		end

	set_restore_when_closed (state: BOOLEAN)
		-- Automatically restore the box to its original position when the new 
		-- dialog is closed. Default: "False".
		do
			iup_open.set_attribute(Current, "RESTOREWHENCLOSED", boolean_to_yesno(state))
		end

	set_show_grip (state: BOOLEAN)
		-- (non inheritable): Shows the bar grip affordance. Default: YES. When 
		-- set to NO, the BARSIZE is set to 5 (if greater than 5). To completely 
		-- hide the bar set BARSIZE to 0.
		do
			iup_open.set_attribute(Current, "SHOWGRIP", boolean_to_yesno(state))
		end

	is_show_grip: BOOLEAN
		-- Return the state of show grip.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "SHOWGRIP")
			Result := yesno_to_boolean(str)
		end

	-- Callback
	set_cb_detached (act: detachable FUNCTION[TUPLE[IUP_DETACH_BOX, IUP_DIALOG, INTEGER, INTEGER], STRING])
		-- Callback called when the box is detached.
		-- ih: identifier of the element that activated the event.
		-- new_parent: identifier of the future parent of the box. At this point 
		-- only the PARENTDIALOG attribute was set.
		-- x, y: dropped position.
		--
		-- Returns: IUP_IGNORE will be processed, in order to cancel the detach 
		-- action.
		local
			operation: INTEGER
		do
			cb_detached := act

			if cb_detached /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "DETACHED_CB", "NONEEDED", operation)
		end

	set_cb_restored (act: detachable FUNCTION[TUPLE[IUP_DETACH_BOX, IUP_WIDGET, INTEGER, INTEGER], STRING])
		-- Callback called when the box is restored if RESTOREWHENCLOSED=Yes.
		--
		-- ih: identifier of the element that activated the event.
		-- old_parent: identifier of the original parent of the box.
		-- x, y: always 0,0.
		--
		-- Returns: IUP_IGNORE will be processed, in order to cancel the
		-- detach action.
		local
			operation: INTEGER
		do
			cb_restored := act

			if cb_restored /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "RESTORED_CB", "NONEEDED", operation)
		end

feature {IUP}
	
	-- Callback
	
	execute_detached (new_parent: IUP_DIALOG; x, y: INTEGER): STRING
		do
			if attached cb_detached as int_cb then
				Result := int_cb.item([Current, new_parent, x, y])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_restored (old_parent: IUP_WIDGET; x, y: INTEGER): STRING
		do
			if attached cb_restored as int_cb then
				Result := int_cb.item([Current, old_parent, x, y])
			else
				Result := "IUP_DEFAULT"
			end
		end
	
feature {NONE}

	-- For callbacks
	
	cb_detached: detachable FUNCTION[TUPLE[IUP_DETACH_BOX, IUP_DIALOG, INTEGER, INTEGER], STRING]
	cb_restored: detachable FUNCTION[TUPLE[IUP_DETACH_BOX, IUP_WIDGET, INTEGER, INTEGER], STRING]

	-- Internals
	
	int_detach_box (child: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupDetachBox ($child);"
      end

	-- Validations

	is_valid_orientation (value: STRING): BOOLEAN
		do
			if value.is_equal("HORIZONTAL") or
				value.is_equal("VERTICAL") then
				Result := True
			else
				Result := False
			end
		end

end

-- The MIT License (MIT)

-- Copyright (c) 2016, 2017, 2019, 2020 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.

